package com.czp.manager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import com.jfinal.core.Controller;
import com.jfinal.upload.UploadFile;

/**
 * Copyright 2014 李松泉 
 * 功能说明：TODO 
 * 开发时间：2014-1-7下午8:41:09
 * 开发作者：李松泉
 * 本地测试地址：http://localhost/czp 
 */

//访问地址：http://localhost:8080/czpupdatemanager/czp/
public class CZPFileController extends Controller{
	
	private static String path = "czpFile/upload";
	private String outputEncoding = "UTF-8"; // DOM4J默认的编码格式为utf-8,所以含有中文时需要指定中文编码，不含中文倒不需要重写编码格式的
	private File xmlfile = null;
	private List<FileBean> fileNameList = new ArrayList<FileBean>();
	
	public File getXmlfile() {
		return xmlfile;
	}

	public void setXmlfile(File xmlfile) {
		this.xmlfile = xmlfile;
	}
	
	public String getOutputEncoding() {
		return outputEncoding;
	}

	public void setOutputEncoding(String outputEncoding) {
		this.outputEncoding = outputEncoding;
	}
	
	/**
	 * 解析xml为Document，放入内存中
	 * 
	 * @param filepath
	 * @return
	 * @throws DocumentException
	 */
	public Document parse(File xmlfile) {
		this.xmlfile = xmlfile;
		SAXReader reader = new SAXReader();
		Document document = null;
		try {
			document = reader.read(xmlfile);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return document;
	}
	
	public void index(){
		getSession().removeAttribute("uploadFilePath");
		String basePath = getSession().getServletContext().getRealPath("");
		if (xmlfile == null) {
			xmlfile = new File(basePath + "/" + path+"/updateconfig.xml");
		}
		File rootFile = new File(basePath +"/"+ path);
		if(!rootFile.exists())
			rootFile.mkdirs();
		if(rootFile.isDirectory()){
			File[] filesArray1 = rootFile.listFiles();
			String realPathStr = rootFile.getAbsolutePath().substring(rootFile.getAbsolutePath().indexOf("upload"));
			String absolutePath = rootFile.getAbsolutePath();
			int i = absolutePath.lastIndexOf(basePath)+basePath.length();
			absolutePath = absolutePath.substring(i);
			if(rootFile.getAbsolutePath().contains("\\"))
				absolutePath = absolutePath.replaceAll("\\\\", "`");
			else
				absolutePath = absolutePath.replaceAll("/", "`");
			if(absolutePath.contains("_"))
				absolutePath = absolutePath.replace("_", "@");
			if(absolutePath.contains("."))
				absolutePath = absolutePath.replace(".", "!");
			if(absolutePath.contains("-"))
				absolutePath = absolutePath.replace("-", "~");
			setAttr("absolutePath", absolutePath);
			setAttr("realPath", realPathStr);
			for(File fileTemp : filesArray1){
				String fileNameTemp = fileTemp.getName();
				long longTime = fileTemp.lastModified();
				Date date = new Date(longTime);
				java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String time = format.format(date);
				FileBean fb = new FileBean();
				fb.setFileName(fileNameTemp);
				fb.setTime(time);
				if(fileTemp.isDirectory())
					fb.setIsDirectory("0");
				fileNameList.add(fb);
			}
			setAttr("fileNameList", fileNameList);
		}
		render("list.jsp");
	}
	
	/**
	 * 上传文件保存，并更新配置文件
	 */
	@SuppressWarnings("rawtypes")
	public void save(){
		HttpSession session = getSession();
		String basePath = getSession().getServletContext().getRealPath("");
		if (xmlfile == null) {
			xmlfile = new File(basePath + "/" + path+"/updateconfig.xml");
		}
		String uploadFilePath = session.getAttribute("uploadFilePath").toString();
		List<UploadFile> fileList = getFiles(uploadFilePath);//获取表单上传的文件
		Document doc = parse(xmlfile);//解析服务端配置文件
		List<String> fileNameList = new ArrayList<String>();
		if(fileList.size() == 0)
			return;
		for(UploadFile fileTemp : fileList){
			String originalFileName = fileTemp.getOriginalFileName();
			String fileName = fileTemp.getFileName();
			fileNameList.add(originalFileName);
			File file1 = new File(uploadFilePath +"/"+originalFileName);//根据上传文件的原文件名获取服务器上对应的文件(上传到服务端时可能由于冲突重命名了，所以获取原文件名)
			if(!fileName.equals(originalFileName)){//如果上传的文件在服务端存在，则先删除
				file1.delete();
				File file2 = new File(uploadFilePath +"/"+fileTemp.getFileName());
				file2.renameTo(file1);//再把新上传的文件重命名问原始名称
			}
			List list = doc.selectNodes("Info/Files/File");//获取配置文件中的File的节点的list
			Iterator iter = list.iterator();
			boolean flag = false;
			while (iter.hasNext()) {//遍历File节点
				Element element = (Element) iter.next();
				String serverFileName = element.element("Name").getText();//获取File节点下Name节点的值，也就是文件名称
				if(serverFileName.equals(file1.getName())){
					String versionStr = element.element("SubVer").getText();//获取文件版本号
					String temp = versionStr.substring(versionStr.lastIndexOf(".")+1);
					int version = Integer.parseInt(temp);
					Date date = new Date();
					java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					String time = format.format(date);
					long longTime = date.getTime();//设置文件的修改时间
					file1.setLastModified(longTime);
					String filePath = uploadFilePath.substring(uploadFilePath.indexOf("upload")+6);
					if(filePath.equals(""))
						filePath = ".\\";
					else
						filePath = "."+filePath;
					String newVersionStr = versionStr.substring(0, versionStr.lastIndexOf(".")+1)+(version+1);//生成新的版本号
					element.element("SubVer").setText(newVersionStr);//更新单个File节点的版本记录
					element.element("Path").setText(filePath);
					element.element("Time").setText(time);
					flag = true;
					break;
				}
			}
			if(!flag){
				//如果在配置文件中不能找到版本记录则添加
				List list1 = doc.selectNodes("Info/Files");
				Iterator iter1 = list1.iterator();
				while (iter1.hasNext()) {
					Element element = (Element) iter1.next();
					Element newFile = element.addElement("File");//创建File节点
					Element newName = newFile.addElement("Name");//创建Name节点
					Date date = new Date();
					java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					String time = format.format(date);
					long longTime = date.getTime();
					file1.setLastModified(longTime);
					String filePath = uploadFilePath.substring(uploadFilePath.indexOf("upload")+6);
					if(filePath.equals(""))
						filePath = ".\\";
					else
						filePath = "."+filePath;
					Element newPath = newFile.addElement("Path");//创建Path节点
					Element newSubVer = newFile.addElement("SubVer");//创建SubVer节点
					Element newTime = newFile.addElement("Time");
					newName.setText(originalFileName);//为Name节点赋值
					newPath.setText(filePath);//为Path节点赋值
					newSubVer.setText("1.0.0.1");//为SubVer节点赋值
					newTime.setText(time);//设置时间
					break;
				}
			}
		}
		
		List list = doc.selectNodes("Info/Version");//更新整个配置文件的版本号
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			Element element = (Element) iter.next();
			String versionStr = element.getText();
			String temp = versionStr.substring(versionStr.lastIndexOf(".")+1);
			int version = Integer.parseInt(temp);
			String newVersionStr = versionStr.substring(0, versionStr.lastIndexOf(".")+1)+(version+1);
			element.setText(newVersionStr);
		}
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding(outputEncoding);
		XMLWriter output;
		try {
			output = new XMLWriter(new FileOutputStream (xmlfile), format);//写入
			output.write(doc);
			output.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		setAttr("uploadFilePath", uploadFilePath.substring(uploadFilePath.indexOf("upload")));
		setAttr("fileNameList", fileNameList);
		render("upload-success.jsp");
	}
	
	/**
	 * 由列表进入文件夹
	 * @throws Exception
	 */
	public void fileInfo() throws Exception{
		String basePath = getSession().getServletContext().getRealPath("");
		String fileName = new String(getPara(0).getBytes("ISO-8859-1"), "utf-8");;
		fileName = URLDecoder.decode(fileName, "utf-8");
		if(fileName.contains("@"))
			fileName = URLDecoder.decode(fileName.replaceAll("@", "_"), "UTF-8");
		if(fileName.contains("!"))
			fileName = URLDecoder.decode(fileName.replaceAll("!", "."), "UTF-8");
		if(fileName.contains("~"))
			fileName = URLDecoder.decode(fileName.replaceAll("~", "-"), "UTF-8");
		String sPara = new String(getPara(1).getBytes("ISO-8859-1"), "utf-8");;
		sPara = URLDecoder.decode(sPara, "utf-8");
		String relativePathStr = URLDecoder.decode(sPara, "UTF-8").replaceAll("`", "/");
		if(relativePathStr.contains("@"))
			relativePathStr = relativePathStr.replace("@", "_");
		if(relativePathStr.contains("!"))
			relativePathStr = relativePathStr.replace("!", ".");
		if(relativePathStr.contains("~"))
			relativePathStr = relativePathStr.replace("~", "-");
		relativePathStr =basePath + URLDecoder.decode(relativePathStr, "UTF-8");
		File thisFile = new File(relativePathStr+"/"+fileName);
		if(!thisFile.isDirectory())
			renderJson("");
		else
			findFile(thisFile);
	}
	
	/**
	 * 由目录进入文件夹
	 * @throws Exception
	 */
	public void fileIn() throws Exception{
		String basePath = getSession().getServletContext().getRealPath("");
		String fileName = new String(getPara(0).getBytes("ISO-8859-1"), "utf-8");;
		fileName = URLDecoder.decode(fileName, "utf-8");
		if(fileName.contains("@"))
			fileName = URLDecoder.decode(fileName.replaceAll("@", "_"), "UTF-8");
		if(fileName.contains("!"))
			fileName = URLDecoder.decode(fileName.replaceAll("!", "."), "UTF-8");
		if(fileName.contains("~"))
			fileName = URLDecoder.decode(fileName.replaceAll("~", "-"), "UTF-8");
		if(fileName.equals("upload"))
			redirect("/index");
		String sPara = new String(getPara(1).getBytes("ISO-8859-1"), "utf-8");;
		sPara = URLDecoder.decode(sPara, "utf-8");
		String absolutePath = URLDecoder.decode(sPara, "UTF-8").replaceAll("`", "/");
		if(absolutePath.contains("@"))
			absolutePath = URLDecoder.decode(absolutePath, "UTF-8").replaceAll("@", "_");
		if(absolutePath.contains("!"))
			absolutePath = URLDecoder.decode(absolutePath, "UTF-8").replaceAll("!", ".");
		if(absolutePath.contains("~"))
			absolutePath = URLDecoder.decode(absolutePath, "UTF-8").replaceAll("~", "-");
		String filePath = basePath + absolutePath.substring(0, absolutePath.indexOf(fileName))+fileName;
		File file = new File(filePath);
		findFile(file);
	}
	
	/**
	 * 查找当前文件夹下的文件
	 * @param thisFile
	 */
	public void findFile(File thisFile){
		String basePath = getSession().getServletContext().getRealPath("");
		File[] filesArray2 = thisFile.listFiles();//获取文件集
		String realPathStr = thisFile.getAbsolutePath().substring(thisFile.getAbsolutePath().indexOf("upload"));//获取相对路径，用于页面显示目录
		if(realPathStr.contains("\\"))
			realPathStr = realPathStr.replaceAll("\\\\", "/");
		String absolutePath = thisFile.getAbsolutePath();
		int i = absolutePath.lastIndexOf(basePath)+basePath.length();
		absolutePath = absolutePath.substring(i);
		if(absolutePath.contains("\\"))
			absolutePath = absolutePath.replace("\\", "`");//获取文件夹的绝对路径，并把"\"替换成_，用于上传文件时获取当前路径
		else
			absolutePath = absolutePath.replace("/", "`");//获取文件夹的绝对路径，并把"\"替换成_，用于上传文件时获取当前路径
		if(absolutePath.contains("_"))
			absolutePath = absolutePath.replace("_", "@");
		if(absolutePath.contains("."))
			absolutePath = absolutePath.replace(".", "!");
		if(absolutePath.contains("-"))
			absolutePath = absolutePath.replace("-", "~");
		setAttr("absolutePath", absolutePath);
		String[] pathArray = realPathStr.split("/");
		setAttr("pathArray", pathArray);
		for(File fileTemp : filesArray2){
			String fileNameTemp = fileTemp.getName();
			long longTime = fileTemp.lastModified();
			Date date = new Date(longTime);
			java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String time = format.format(date);
			FileBean fb = new FileBean();
			fb.setFileName(fileNameTemp);
			fb.setTime(time);
			if(fileTemp.isDirectory())
				fb.setIsDirectory("0");
			fileNameList.add(fb);
		}
		setAttr("fileNameList", fileNameList);
		render("list-ajax.jsp");
	}
	
	/**
	 * 删除文件，当文件是文件夹，并且不为空时不允许删除，删除了文件之后更新配置文件，删除相应文件的版本信息
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public void deleteFile() throws Exception{
		String basePath = getSession().getServletContext().getRealPath("");
		if (xmlfile == null) {
			xmlfile = new File(basePath + "/" + path+"/updateconfig.xml");
		}
		String fileName = new String(getPara(0).getBytes("ISO-8859-1"), "utf-8");;
		fileName = URLDecoder.decode(fileName, "utf-8"); //获取第一个参数，也就是文件名
		if(fileName.contains("!"))
			fileName = fileName.replace("!", ".");//文件名参数在传之前"."被转换成"_"，现在转回来
		if(fileName.contains("@"))
			fileName = fileName.replace("@", "_");//文件名参数在传之前"."被转换成"_"，现在转回来
		if(fileName.contains("~"))
			fileName = fileName.replace("~", "-");
		String sPara = new String(getPara(1).getBytes("ISO-8859-1"), "utf-8");;
		sPara = URLDecoder.decode(sPara, "utf-8");
		String relativePathStr =  URLDecoder.decode(sPara, "UTF-8").replaceAll("`", "/");//获取第二个参数，也就是路径
		if(relativePathStr.contains("@"))
			relativePathStr = relativePathStr.replace("@", "_");
		if(relativePathStr.contains("!"))
			relativePathStr = relativePathStr.replace("!", ".");
		if(relativePathStr.contains("~"))
			relativePathStr = relativePathStr.replace("~", "-");
		relativePathStr = basePath + URLDecoder.decode(relativePathStr, "UTF-8");
		File thisFile = new File(relativePathStr+"/"+fileName);
		if(thisFile.isDirectory() && thisFile.listFiles().length > 0)
			renderJson("FolderIsNotNull");//如果文件夹不为空，不允许删除
		else{
			if(thisFile.exists())
				thisFile.delete();
			if(!thisFile.isDirectory()){
				Document doc = parse(xmlfile);//解析服务端配置文件
				List list = doc.selectNodes("Info/Files/File");//获取配置文件中的File的节点的list
				Iterator iter = list.iterator();
				while (iter.hasNext()) {//遍历File节点
					Element element = (Element) iter.next();
					String serverFileName = element.element("Name").getText();//获取File节点下Name节点的值，也就是文件名称
					if(serverFileName.equals(fileName)){
						element.getParent().remove(element);
						break;
					}
				}
				OutputFormat format = OutputFormat.createPrettyPrint();
				format.setEncoding(outputEncoding);
				XMLWriter output;
				try {
					output = new XMLWriter(new FileOutputStream (xmlfile), format);//写入
					output.write(doc);
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				findFile(new File(relativePathStr));//重新遍历当前目录
			}
		}
	}
	
	/**
	 * 创建文件夹
	 * @throws Exception
	 */
	public void createFolder() throws Exception{
		String basePath = getSession().getServletContext().getRealPath("");
		String sPara = new String(getPara(0).getBytes("ISO-8859-1"), "utf-8");;
		sPara = URLDecoder.decode(sPara, "utf-8");
		String absolutePath = basePath + URLDecoder.decode(sPara, "UTF-8").replaceAll("`", "/");
		if(absolutePath.contains("@"))
			absolutePath = absolutePath.replace("@", "_");
		if(absolutePath.contains("!"))
			absolutePath = absolutePath.replace("!", ".");
		if(absolutePath.contains("~"))
			absolutePath = absolutePath.replace("~", "-");
		String fileName = new String(getPara(1).getBytes("ISO-8859-1"), "utf-8");;
		fileName = URLDecoder.decode(fileName, "utf-8");
		if(fileName.contains("!"))
			fileName = fileName.replace("!", ".");//文件名参数在传之前"."被转换成"_"，现在转回来
		if(fileName.contains("@"))
			fileName = fileName.replace("@", "_");//文件名参数在传之前"."被转换成"_"，现在转回来
		if(fileName.contains("~"))
			fileName = fileName.replace("~", "-");
		File newFile = new File(absolutePath+"/"+fileName);
		newFile.mkdirs();
		findFile(new File(absolutePath));
	}
	
	/**
	 * 上一级目录
	 * @throws Exception
	 */
	public void parentFolder() throws Exception{
		String basePath = getSession().getServletContext().getRealPath("");
		String sPara = new String(getPara(0).getBytes("ISO-8859-1"), "utf-8");;
		sPara = URLDecoder.decode(sPara, "utf-8");
		String absolutePath = basePath + URLDecoder.decode(sPara, "UTF-8").replaceAll("`", "/");
		if(absolutePath.contains("@"))
			absolutePath = absolutePath.replace("@", "_");
		if(absolutePath.contains("!"))
			absolutePath = absolutePath.replace("!", ".");
		if(absolutePath.contains("~"))
			absolutePath = absolutePath.replace("~", "-");
		File file = new File(absolutePath);
		if(file.getName().equals("upload") || !absolutePath.contains("upload"))
			findFile(file);
		else
			findFile(file.getParentFile());
	}
	
	/**
	 * 上传文件方法
	 * @throws Exception
	 */
	public void uploadFile() throws Exception{
		String basePath = getSession().getServletContext().getRealPath("");
		String absolutePath = "";
		if(getPara(0) != null){
			String sPara = new String(getPara(0).getBytes("ISO-8859-1"), "utf-8");;
			sPara = URLDecoder.decode(sPara, "utf-8");
			absolutePath = basePath + URLDecoder.decode(sPara, "UTF-8").replaceAll("`", "/");
			if(absolutePath.contains("@"))
				absolutePath = absolutePath.replace("@", "_");
			if(absolutePath.contains("!"))
				absolutePath = absolutePath.replace("!", ".");
			if(absolutePath.contains("~"))
				absolutePath = absolutePath.replace("~", "-");
			setSessionAttr("uploadFilePath", absolutePath);
		}else
			absolutePath = basePath + getSession().getAttribute("uploadFilePath").toString();
		setAttr("uploadFilePath", absolutePath.substring(absolutePath.indexOf("upload")));
		render("file-input.jsp");
	}
}
